home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Reference / FAQs on CD / comp.lang.obj-C FAQ (3⁄3) samp < prev    next >
Encoding:
Text File  |  1997-04-24  |  24.0 KB  |  965 lines  |  [TEXT/R*ch]

  1. Newsgroups: comp.lang.objective-c,comp.answers,news.answers
  2. From: tiggr@es.ele.tue.nl (Tiggr)
  3. Subject: comp.lang.objective-c FAQ, part 3/3: A Sample Program
  4. Summary: This third part of the comp.lang.objective-c FAQ postings
  5.         presents a simple sample program written in Objective-C.
  6. Reply-To: tiggr@es.ele.tue.nl (Tiggr)
  7. Followup-To: comp.lang.objective-c
  8. Organization: Eindhoven University of Technology
  9. Approved: news-answers-request@mit.edu
  10. Keywords:
  11.  
  12. Archive-name: Objective-C/sample
  13. Version: $Id: sample.preamble,v 3.7 1996/03/20 11:38:17 tiggr Exp $
  14.  
  15.  
  16.         A simple sample
  17.         Objective-C program
  18.  
  19.  
  20. This is the third part in a series of three informational postings
  21. concerning comp.lang.objective-c.  This article presents a simple program
  22. written in Objective-C.  The program consist of several files which are
  23. contained in a shar file (see instructions below on how to unpack).  [Note,
  24. from version 2.3 of this file, the sample has been changed in order to
  25. reduce the number of compiler warnings (down to 1, which is in there for
  26. explanatory purposes) and to reflect the use of `+alloc' and `-init' instead
  27. of `+new'.]
  28.  
  29. The early version of this FAQ was compiled by Bill Shirley, with the aid of
  30. many people.  The current version is being maintained by Tiggr, aided by a
  31. lot of people, including Paul Sanchez and Bill Shirley.
  32.  
  33. A Japanese language version of this FAQ is maintained by Norihiro Itoh
  34. <nito@argotechnos.co.jp>.  It is posted to fj.archives.answers
  35. regularly.  A hypertext version is maintained by Toru Sato
  36. <www-admin@cnds.canon.co.jp> and available at:
  37. http://www.cnds.canon.co.jp/Japanese_EUC/Contribution/FAQ_Objective-C/objc_faq_J.html
  38.  
  39. A World Wide Web hypertext version of this FAQ is maintained by Brian Harvey
  40. <theharv@csld.ucr.edu>.  It is http://csld.ucr.edu/NeXTSTEP/objc_faq.html.
  41. Another WWW version of this FAQ is maintained by Steve Dekorte
  42. <dekorte@suite.com> at http://www.batech.com/~dekorte/Objective-C/objc.html
  43.  
  44. Send your suggestions, additions, bug reports, comments and fixes to
  45. `tiggr@es.ele.tue.nl'.
  46.  
  47. #---------------------------------- cut here ----------------------------------
  48. # This is a shell archive.  Remove anything before this line,
  49. # then unpack it by saving it in a file and typing "sh file".
  50. #
  51. # Wrapped by Pieter Schoenmakers <tiggr@cobra> on Thu Oct 10 11:27:05 1996
  52. #
  53. # This archive contains:
  54. #    objc-sample    
  55. #
  56. # Existing files will not be overwritten.
  57. # Error checking via wc(1) will be performed.
  58.  
  59. LANG=""; export LANG
  60. PATH=/bin:/usr/bin:$PATH; export PATH
  61.  
  62. echo mkdir - objc-sample
  63. mkdir objc-sample
  64.  
  65. if test -f objc-sample/Char.h
  66. then
  67.     echo Ok to overwrite existing file objc-sample/Char.h\?
  68.     read answer
  69.     case "$answer" in
  70.     [yY]*)    echo Proceeding;;
  71.     *)    echo Aborting; exit 1;;
  72.     esac
  73.     rm -f objc-sample/Char.h
  74.     if test -f objc-sample/Char.h
  75.     then
  76.         echo Error: could not remove objc-sample/Char.h, aborting
  77.         exit 1
  78.     fi
  79. fi
  80. echo x - objc-sample/Char.h
  81. cat >objc-sample/Char.h <<'__EOF__'
  82. #import <objc/Object.h>
  83.  
  84. @interface Char: Object
  85. {
  86.   int value;
  87. }
  88.  
  89. -init: (int) x;
  90. -report;
  91.  
  92. @end
  93. __EOF__
  94. set `wc -lwc <objc-sample/Char.h`
  95. if test $1$2$3 != 111498
  96. then
  97.     echo ERROR: wc results of objc-sample/Char.h are $* should be 11 14 98
  98. fi
  99.  
  100. chmod 644 objc-sample/Char.h
  101.  
  102. if test -f objc-sample/Char.m
  103. then
  104.     echo Ok to overwrite existing file objc-sample/Char.m\?
  105.     read answer
  106.     case "$answer" in
  107.     [yY]*)    echo Proceeding;;
  108.     *)    echo Aborting; exit 1;;
  109.     esac
  110.     rm -f objc-sample/Char.m
  111.     if test -f objc-sample/Char.m
  112.     then
  113.         echo Error: could not remove objc-sample/Char.m, aborting
  114.         exit 1
  115.     fi
  116. fi
  117. echo x - objc-sample/Char.m
  118. cat >objc-sample/Char.m <<'__EOF__'
  119. #import <stdio.h>
  120. #import "Char.h"
  121.  
  122. @implementation Char
  123. {
  124.   int value;
  125. }
  126.  
  127. - init: (int) x
  128. {
  129.   [super init];        // In case the parent class is doing
  130.               // something special in its init...
  131.   value = x;
  132.   return self;
  133. }
  134.  
  135. - report
  136. {
  137.   printf("   %c", value);
  138.   return self;
  139. }
  140.  
  141. @end
  142. __EOF__
  143. set `wc -lwc <objc-sample/Char.m`
  144. if test $1$2$3 != 2347279
  145. then
  146.     echo ERROR: wc results of objc-sample/Char.m are $* should be 23 47 279
  147. fi
  148.  
  149. chmod 644 objc-sample/Char.m
  150.  
  151. if test -f objc-sample/Float.h
  152. then
  153.     echo Ok to overwrite existing file objc-sample/Float.h\?
  154.     read answer
  155.     case "$answer" in
  156.     [yY]*)    echo Proceeding;;
  157.     *)    echo Aborting; exit 1;;
  158.     esac
  159.     rm -f objc-sample/Float.h
  160.     if test -f objc-sample/Float.h
  161.     then
  162.         echo Error: could not remove objc-sample/Float.h, aborting
  163.         exit 1
  164.     fi
  165. fi
  166. echo x - objc-sample/Float.h
  167. cat >objc-sample/Float.h <<'__EOF__'
  168. #import <objc/Object.h>
  169.  
  170. @interface Float: Object
  171. {
  172.   float value;
  173. }
  174.  
  175. -initFloatValue: (float) x;
  176. -report;
  177.  
  178. @end
  179. __EOF__
  180. set `wc -lwc <objc-sample/Float.h`
  181. if test $1$2$3 != 1114113
  182. then
  183.     echo ERROR: wc results of objc-sample/Float.h are $* should be 11 14 113
  184. fi
  185.  
  186. chmod 644 objc-sample/Float.h
  187.  
  188. if test -f objc-sample/Float.m
  189. then
  190.     echo Ok to overwrite existing file objc-sample/Float.m\?
  191.     read answer
  192.     case "$answer" in
  193.     [yY]*)    echo Proceeding;;
  194.     *)    echo Aborting; exit 1;;
  195.     esac
  196.     rm -f objc-sample/Float.m
  197.     if test -f objc-sample/Float.m
  198.     then
  199.         echo Error: could not remove objc-sample/Float.m, aborting
  200.         exit 1
  201.     fi
  202. fi
  203. echo x - objc-sample/Float.m
  204. cat >objc-sample/Float.m <<'__EOF__'
  205. #import <stdio.h>
  206. #import "Float.h"
  207.  
  208. @implementation Float
  209. {
  210.   float value;
  211. }
  212.  
  213. -initFloatValue: (float) x
  214. {
  215.   [super init];
  216.   value = x;
  217.   return self;
  218. }
  219.  
  220. -report
  221. {
  222.   printf ("%4.1f", value);
  223.   return self;
  224. }
  225.  
  226. @end
  227. __EOF__
  228. set `wc -lwc <objc-sample/Float.m`
  229. if test $1$2$3 != 2231215
  230. then
  231.     echo ERROR: wc results of objc-sample/Float.m are $* should be 22 31 215
  232. fi
  233.  
  234. chmod 644 objc-sample/Float.m
  235.  
  236. if test -f objc-sample/Makefile
  237. then
  238.     echo Ok to overwrite existing file objc-sample/Makefile\?
  239.     read answer
  240.     case "$answer" in
  241.     [yY]*)    echo Proceeding;;
  242.     *)    echo Aborting; exit 1;;
  243.     esac
  244.     rm -f objc-sample/Makefile
  245.     if test -f objc-sample/Makefile
  246.     then
  247.         echo Error: could not remove objc-sample/Makefile, aborting
  248.         exit 1
  249.     fi
  250. fi
  251. echo x - objc-sample/Makefile
  252. cat >objc-sample/Makefile <<'__EOF__'
  253. # This Makefile assumes you have GNU gcc 2.3 or better and a suitable
  254. # runtime library with object support.  It also works on a NeXT.
  255. # Don't know about Stepstone.
  256.  
  257. .SUFFIXES: .o .m
  258. .m.o:
  259.     $(CC) -c $(CFLAGS) $<
  260.  
  261. # Use this on a NeXT
  262. #CC=        cc
  263. #LIBS=        
  264. # Use this with GNU CC on a non-NeXT,
  265. # and avoid the GCC moaning on using #import.
  266. CC=        gcc -Wno-import
  267. LIBS=        -lobjc
  268. LDFLAGS=    -L/usr/local/lib -L/usr/gnu/lib
  269.  
  270. CFLAGS=        -Wall -g
  271. OFILES=        main.o Node.o Queue.o Stack.o Float.o Char.o
  272.  
  273. demo: $(OFILES)
  274.     $(CC) $(CFLAGS) $(LDFLAGS) -o demo $(OFILES) $(LIBS)
  275.  
  276. clean:
  277.     rm -f $(OFILES) demo
  278.     
  279. Char.o : Char.m Char.h 
  280.  
  281. Float.o : Float.m Float.h 
  282.  
  283. Node.o : Node.m Node.h 
  284.  
  285. Queue.o : Queue.m Queue.h Node.h 
  286.  
  287. Stack.o : Stack.m Stack.h Node.h 
  288.  
  289. main.o : main.m Queue.h Node.h Stack.h Float.h
  290. __EOF__
  291. set `wc -lwc <objc-sample/Makefile`
  292. if test $1$2$3 != 37127783
  293. then
  294.     echo ERROR: wc results of objc-sample/Makefile are $* should be 37 127 783
  295. fi
  296.  
  297. chmod 644 objc-sample/Makefile
  298.  
  299. if test -f objc-sample/Node.h
  300. then
  301.     echo Ok to overwrite existing file objc-sample/Node.h\?
  302.     read answer
  303.     case "$answer" in
  304.     [yY]*)    echo Proceeding;;
  305.     *)    echo Aborting; exit 1;;
  306.     esac
  307.     rm -f objc-sample/Node.h
  308.     if test -f objc-sample/Node.h
  309.     then
  310.         echo Error: could not remove objc-sample/Node.h, aborting
  311.         exit 1
  312.     fi
  313. fi
  314. echo x - objc-sample/Node.h
  315. cat >objc-sample/Node.h <<'__EOF__'
  316. #import <objc/Object.h>
  317.  
  318. @interface Node : Object
  319. {
  320.   id next;
  321.   id data;
  322. }
  323.  
  324. -init: anItem;        // create a Node and store anItem in it
  325. -free;            // free a Node and return the item in it
  326. -next;            // report the id of the next node after this one
  327. -setNext: aNode;    // make the next node be aNode
  328.  
  329. @end
  330. __EOF__
  331. set `wc -lwc <objc-sample/Node.h`
  332. if test $1$2$3 != 1456295
  333. then
  334.     echo ERROR: wc results of objc-sample/Node.h are $* should be 14 56 295
  335. fi
  336.  
  337. chmod 644 objc-sample/Node.h
  338.  
  339. if test -f objc-sample/Node.m
  340. then
  341.     echo Ok to overwrite existing file objc-sample/Node.m\?
  342.     read answer
  343.     case "$answer" in
  344.     [yY]*)    echo Proceeding;;
  345.     *)    echo Aborting; exit 1;;
  346.     esac
  347.     rm -f objc-sample/Node.m
  348.     if test -f objc-sample/Node.m
  349.     then
  350.         echo Error: could not remove objc-sample/Node.m, aborting
  351.         exit 1
  352.     fi
  353. fi
  354. echo x - objc-sample/Node.m
  355. cat >objc-sample/Node.m <<'__EOF__'
  356. #import <objc/Object.h>
  357. #import "Node.h"
  358.  
  359. @implementation    Node: Object
  360.  
  361. -init: anItem
  362. {
  363.   self = [super init];
  364.   next = 0;
  365.   data = anItem;
  366.   return self;
  367. }
  368.  
  369. -free
  370. {
  371.   id tmp = data;
  372.   [super free];
  373.   return tmp;
  374. }
  375.  
  376. -next
  377. {
  378.   return next;
  379. }
  380.  
  381. -setNext: aNode
  382. {
  383.   next = aNode;
  384.   return self;
  385. }
  386.  
  387. @end
  388. __EOF__
  389. set `wc -lwc <objc-sample/Node.m`
  390. if test $1$2$3 != 3249299
  391. then
  392.     echo ERROR: wc results of objc-sample/Node.m are $* should be 32 49 299
  393. fi
  394.  
  395. chmod 644 objc-sample/Node.m
  396.  
  397. if test -f objc-sample/Queue.h
  398. then
  399.     echo Ok to overwrite existing file objc-sample/Queue.h\?
  400.     read answer
  401.     case "$answer" in
  402.     [yY]*)    echo Proceeding;;
  403.     *)    echo Aborting; exit 1;;
  404.     esac
  405.     rm -f objc-sample/Queue.h
  406.     if test -f objc-sample/Queue.h
  407.     then
  408.         echo Error: could not remove objc-sample/Queue.h, aborting
  409.         exit 1
  410.     fi
  411. fi
  412. echo x - objc-sample/Queue.h
  413. cat >objc-sample/Queue.h <<'__EOF__'
  414. #import <objc/Object.h>
  415. #import "Node.h"
  416.  
  417. @interface Queue: Object
  418. {
  419.   id head;
  420.   id tail;
  421.   unsigned qsize;
  422. }
  423.  
  424. -empty;            // clear out all contents of the Queue
  425. -put: anItem;        // put anItem on the Queue
  426. -get;            // return the item on top of the Queue
  427. -(unsigned int) size;    // tell us the current size of the Queue
  428.  
  429. @end
  430. __EOF__
  431. set `wc -lwc <objc-sample/Queue.h`
  432. if test $1$2$3 != 1655319
  433. then
  434.     echo ERROR: wc results of objc-sample/Queue.h are $* should be 16 55 319
  435. fi
  436.  
  437. chmod 644 objc-sample/Queue.h
  438.  
  439. if test -f objc-sample/Queue.m
  440. then
  441.     echo Ok to overwrite existing file objc-sample/Queue.m\?
  442.     read answer
  443.     case "$answer" in
  444.     [yY]*)    echo Proceeding;;
  445.     *)    echo Aborting; exit 1;;
  446.     esac
  447.     rm -f objc-sample/Queue.m
  448.     if test -f objc-sample/Queue.m
  449.     then
  450.         echo Error: could not remove objc-sample/Queue.m, aborting
  451.         exit 1
  452.     fi
  453. fi
  454. echo x - objc-sample/Queue.m
  455. cat >objc-sample/Queue.m <<'__EOF__'
  456. #import "Queue.h"
  457.  
  458. @implementation    Queue
  459.  
  460. -empty
  461. {
  462.   while([self size])
  463.     [[self get] free];
  464.   return self;
  465. }
  466.  
  467. -put: anItem
  468. {
  469.   if (tail)
  470.     tail = [[tail setNext : [[Node alloc] init: anItem]] next];
  471.   else
  472.     head = tail = [[Node alloc] init: anItem];
  473.   ++qsize;
  474.   return self;
  475. }
  476.  
  477. -get
  478. {
  479.   id contents;
  480.   id old_head = head;
  481.  
  482.   head = [head next];
  483.   contents = [old_head free];
  484.   if (--qsize == 0)
  485.     tail = head;
  486.   return contents;
  487. }
  488.  
  489. -(unsigned) size
  490. {
  491.   return qsize;
  492. }
  493.  
  494. @end
  495. __EOF__
  496. set `wc -lwc <objc-sample/Queue.m`
  497. if test $1$2$3 != 3975486
  498. then
  499.     echo ERROR: wc results of objc-sample/Queue.m are $* should be 39 75 486
  500. fi
  501.  
  502. chmod 644 objc-sample/Queue.m
  503.  
  504. if test -f objc-sample/README
  505. then
  506.     echo Ok to overwrite existing file objc-sample/README\?
  507.     read answer
  508.     case "$answer" in
  509.     [yY]*)    echo Proceeding;;
  510.     *)    echo Aborting; exit 1;;
  511.     esac
  512.     rm -f objc-sample/README
  513.     if test -f objc-sample/README
  514.     then
  515.         echo Error: could not remove objc-sample/README, aborting
  516.         exit 1
  517.     fi
  518. fi
  519. echo x - objc-sample/README
  520. cat >objc-sample/README <<'__EOF__'
  521. This directory contains the complete code for the "Simple Sample Objective-C
  522. program" described in the comp.lang.objective-c FAQ.  If you have a suitable
  523. compiler, use the supplied Makefile.  Otherwise, program output can be found
  524. in the file "output".
  525.  
  526. You should probably read "main.m" first.  It is very heavily annotated.
  527.  
  528. Also note and read the file COPYRIGHT.
  529. __EOF__
  530. set `wc -lwc <objc-sample/README`
  531. if test $1$2$3 != 855366
  532. then
  533.     echo ERROR: wc results of objc-sample/README are $* should be 8 55 366
  534. fi
  535.  
  536. chmod 644 objc-sample/README
  537.  
  538. if test -f objc-sample/Stack.h
  539. then
  540.     echo Ok to overwrite existing file objc-sample/Stack.h\?
  541.     read answer
  542.     case "$answer" in
  543.     [yY]*)    echo Proceeding;;
  544.     *)    echo Aborting; exit 1;;
  545.     esac
  546.     rm -f objc-sample/Stack.h
  547.     if test -f objc-sample/Stack.h
  548.     then
  549.         echo Error: could not remove objc-sample/Stack.h, aborting
  550.         exit 1
  551.     fi
  552. fi
  553. echo x - objc-sample/Stack.h
  554. cat >objc-sample/Stack.h <<'__EOF__'
  555. #import <objc/Object.h>
  556. #import "Node.h"
  557.  
  558. @interface Stack: Object
  559. {
  560.   id stack;
  561.   unsigned int stack_size;
  562. }
  563.  
  564. -empty;                // clear out all contents of the Stack
  565. -put: anItem;            // put anItem on the Stack
  566. -get;                // return the item on top of the Stack
  567. -(unsigned) size;        // tell us the current size of the Stack
  568.  
  569. @end
  570. __EOF__
  571. set `wc -lwc <objc-sample/Stack.h`
  572. if test $1$2$3 != 1553318
  573. then
  574.     echo ERROR: wc results of objc-sample/Stack.h are $* should be 15 53 318
  575. fi
  576.  
  577. chmod 644 objc-sample/Stack.h
  578.  
  579. if test -f objc-sample/Stack.m
  580. then
  581.     echo Ok to overwrite existing file objc-sample/Stack.m\?
  582.     read answer
  583.     case "$answer" in
  584.     [yY]*)    echo Proceeding;;
  585.     *)    echo Aborting; exit 1;;
  586.     esac
  587.     rm -f objc-sample/Stack.m
  588.     if test -f objc-sample/Stack.m
  589.     then
  590.         echo Error: could not remove objc-sample/Stack.m, aborting
  591.         exit 1
  592.     fi
  593. fi
  594. echo x - objc-sample/Stack.m
  595. cat >objc-sample/Stack.m <<'__EOF__'
  596. #import "Stack.h"
  597.  
  598. @implementation    Stack
  599.  
  600. -empty
  601. {
  602.   while([self size])
  603.     [[self get] free];
  604.   return self;
  605. }
  606.  
  607. -put: anItem
  608. {
  609.   stack = [[[Node alloc] init: anItem] setNext : stack];
  610.   ++stack_size;
  611.   return self;
  612. }
  613.  
  614. -get
  615. {
  616.   id contents;
  617.   id old_stack = stack;
  618.  
  619.   stack = [stack next];
  620.   contents = [old_stack free];
  621.   --stack_size;
  622.   return contents;
  623. }
  624.  
  625. -(unsigned) size
  626. {
  627.   return stack_size;
  628. }
  629.  
  630. @end
  631. __EOF__
  632. set `wc -lwc <objc-sample/Stack.m`
  633. if test $1$2$3 != 3557407
  634. then
  635.     echo ERROR: wc results of objc-sample/Stack.m are $* should be 35 57 407
  636. fi
  637.  
  638. chmod 644 objc-sample/Stack.m
  639.  
  640. if test -f objc-sample/main.m
  641. then
  642.     echo Ok to overwrite existing file objc-sample/main.m\?
  643.     read answer
  644.     case "$answer" in
  645.     [yY]*)    echo Proceeding;;
  646.     *)    echo Aborting; exit 1;;
  647.     esac
  648.     rm -f objc-sample/main.m
  649.     if test -f objc-sample/main.m
  650.     then
  651.         echo Error: could not remove objc-sample/main.m, aborting
  652.         exit 1
  653.     fi
  654. fi
  655. echo x - objc-sample/main.m
  656. cat >objc-sample/main.m <<'__EOF__'
  657. /* main.m - comp.lang.objective-c simple sample Objective-C program.  */
  658.  
  659. // This is a comment, just like the previous line.  Everything to the right
  660. // of a double slash is ignored.
  661.  
  662. /* Classes are the one real extension which Objective-C adds to C.  A class
  663.    is a description of a collection of data, like a C structure, and the
  664.    methods by which that data may be accessed or manipulated.  Instances of
  665.    a class are called objects, and methods are invoked by sending messages
  666.    to either the class itself, to produce objects, or to those objects.  The
  667.    recipient of a message is called a "receiver".  The form of a message is:
  668.  
  669.     [receiver method andMaybeSomeArguments]
  670.  
  671.    the receiver and method components are mandatory, as are the square
  672.    brackets surrounding the message.  Additional arguments may or may not be
  673.    present, depending upon the method definition.  Messages may appear
  674.    anywhere a statement is allowed in C.
  675.  
  676.    The first thing we do is bring in some include files, as in C.  On the
  677.    NeXT, it is customary to use the "import" statement which guarantees that
  678.    the file isn't included more than once.  Using GNU CC this is not all
  679.    that nice sinds it generates a huge warning for every file being
  680.    compiled.  So, since it does not really matter, we'll stick to
  681.    `#include'.  */
  682.  
  683. #import <stdio.h>
  684. #import <objc/Object.h>
  685. #import "Queue.h"
  686. #import "Stack.h"
  687.  
  688. /* That brought in class definitions for Objects, Queues, and Stacks.  The
  689.    Object class is the basis for all other classes, which is why it gets
  690.    brought in first.  It provides basic functional behavior which is
  691.    inherited by all derived classes.  All user created classes normally have
  692.    Object somewhere in their ancestry.
  693.  
  694.    Queue and Stack are classes of our own construction, and provide FIFO and
  695.    LIFO storage capabilities, respectively.  I'm not going to go into
  696.    implementation details here.  It's irrelevant how they work, all that is
  697.    important is that they both respond to 'put:' and 'get'.  If you want to
  698.    inspect them, look into the Queue.m, Stack.m, Queue.h and Stack.h files.
  699.  
  700.    A simple Class definition follows.  It inherits directly from the base
  701.    class "Object".  This gives it lots of nice properties, not the least of
  702.    which is the ability to be referenced by any pointer of the generic
  703.    object type "id".  All objects can be pointed to by any id variable, and
  704.    the default return type from methods is id.  This allows messages to be
  705.    embedded in other messages, either as receivers or arguments.
  706.  
  707.    An Int object allocates space for a single integer.  The "report" message
  708.    causes it to report its value.  Everything between the @implementation
  709.    and the @end is part of the class definition.
  710.  
  711.    Note - It is *highly* unusual to have a class implementation in your main
  712.    program.  Since the object is fully defined before it gets used, no
  713.    interface description is required.  There is nothing illegal about doing
  714.    things this way, but it is so unusual that the compiler will produce a
  715.    warning for this class.  The Int class implementation is here solely for
  716.    expository purposes.  */
  717.  
  718. @implementation Int: Object    // Int is derived from Object
  719. {
  720.     int value;        // This is the data portion.  Like a struct.
  721. }
  722.  
  723. /* The following are the method definitions.  A `+' prefix means it is a
  724.    factory method, i.e., how to manufacture instances of the class.  The
  725.    body of the method is between braces, like a C function.
  726.  
  727.    This class doesn't define any factory methods.  It relies on the +alloc
  728.    method defined in class Object.  For examples of factory methods, look at
  729.    the +new method defined in the Stack or Queue implementations.
  730.  
  731.    Self is a special variable, which refers to the object currently being
  732.    manipulated.  Super refers to the parent class of self.  The following
  733.    method asks the parent class (Object) to hand us a new instance, which
  734.    becomes self.  Then we update the instance variables and return a pointer
  735.    to the new object.
  736.  
  737.    It is standard for methods that do not need to return any special value
  738.    to instead return self.  This allows for a nested syntax of method calls.
  739.  
  740.    The "-" in front of init means that it's an instance method, i.e.,
  741.    something a particular object should respond to.  */
  742.  
  743. -init: (int) i
  744. {
  745.   /* Have our superclass initialize its part of us.  After that,
  746.      initialize the part of us introduced by this class (Int).  */
  747.   [super init];
  748.   value = i;
  749.   return self;
  750. }
  751.  
  752. -report
  753. {
  754.   printf ("%4d", value);
  755.   return self;
  756. }
  757.  
  758. @end
  759.  
  760. /* We have implemented Float and Char classes more traditionally, using
  761.    separate files for the interface (.h) and implementation (.m).  The Float
  762.    and Char objects are like the Int object, but with the obvious difference
  763.    that they work with floats and characters.  We include the interface
  764.    definitions at this point.  */
  765.  
  766. #import "Float.h"
  767. #import "Char.h"
  768.  
  769. /* If you inspect those files, note polymorphism -- methods have same
  770.    names as in the Int class.  */
  771.  
  772. int main (void)
  773. {
  774.     /* First create instances of "Stack" and "Queue" data structures.  */
  775.     id queue = [[Queue alloc] init];
  776.     id stack = [[Stack alloc] init];
  777.     int i, reply;
  778.     
  779.     fprintf (stderr, "Include the Char class in the demo? (y/n): ");
  780.  
  781.     /* Anything not matching `y.*' means no.  */
  782.     reply = getchar ();
  783.  
  784.     for (i = 5; i > -6; --i)
  785.       {
  786.     /* Depending on which version of the demo we're running, we
  787.        alternately put Ints and Floats onto the queue and stack, or
  788.        Ints, Floats, and Chars.  */
  789.     if (reply == 'y')
  790.       {
  791.         /* If I is odd we put an Int on the queue and a Char on the
  792.            stack.  If I is even we put an Char on the queue and a Float
  793.            on the stack.
  794.  
  795.            Since there is more than one method `-init:' and since
  796.            `+alloc' returns a plain, typeless, `id', the compiler
  797.            doesn't know the type of the object returned by alloc.  An
  798.            explicit cast (i.e. static type indication) ensures that the
  799.            compiler knows which `init:' is invoked---the one accepting a
  800.            char or the other one accepting an int.
  801.  
  802.            Another solution, which avoids the static type indication, is
  803.            to put typing information on the method in the method's name.
  804.            This is done for the Float class.  */
  805.         id my_char = [(Char *) [Char alloc] init: 'm' + i];
  806.  
  807.         if (i & 1)
  808.           {
  809.         [queue put: [(Int *) [Int alloc] init: i]];
  810.         [stack put: my_char];
  811.           }
  812.         else
  813.           {
  814.         [queue put: my_char];
  815.         [stack put: [[Float alloc] initFloatValue: i]];
  816.           }
  817.           }
  818.     else
  819.       {
  820.         /* If I is odd we put an Int on the queue and a Float on the
  821.            stack.  If I is even we put a Float on the queue and an Int
  822.            on the stack.  */
  823.             [queue put: ((i & 1)
  824.              ? [(Int *) [Int alloc] init: i]
  825.              : [[Float alloc] initFloatValue: i])];
  826.             [stack put: ((i & 1)
  827.              ? [[Float alloc] initFloatValue: i]
  828.              : [(Int*) [Int alloc] init: i])];
  829.     }
  830.     }
  831.  
  832.     while ([queue size] && [stack size])
  833.       {
  834.     /* The following illustrates run-time binding.  Will report be
  835.        invoked for a Float object or an Int object?  Did the user elect
  836.        for Char objects at run time?  We don't know ahead of time, but
  837.        with run-time binding and polymorphism it works properly.  The
  838.        burden is on the class implementer rather than the class user.
  839.  
  840.        Note that the following lines remain unchanged, whether we are
  841.        using the Char class or not.  The queue and stack hand us the
  842.        next object, it reports itself regardless of its type, and then
  843.        it frees itself.  */
  844.  
  845.     printf ("queue:");
  846.     [[[queue get] report] free];
  847.     printf (", stack:");
  848.     [[[stack get] report] free];
  849.     putchar('\n');
  850.       }
  851.   return 0;
  852. }
  853. __EOF__
  854. set `wc -lwc <objc-sample/main.m`
  855. if test $1$2$3 != 19612587741
  856. then
  857.     echo ERROR: wc results of objc-sample/main.m are $* should be 196 1258 7741
  858. fi
  859.  
  860. chmod 644 objc-sample/main.m
  861.  
  862. if test -f objc-sample/output
  863. then
  864.     echo Ok to overwrite existing file objc-sample/output\?
  865.     read answer
  866.     case "$answer" in
  867.     [yY]*)    echo Proceeding;;
  868.     *)    echo Aborting; exit 1;;
  869.     esac
  870.     rm -f objc-sample/output
  871.     if test -f objc-sample/output
  872.     then
  873.         echo Error: could not remove objc-sample/output, aborting
  874.         exit 1
  875.     fi
  876. fi
  877. echo x - objc-sample/output
  878. cat >objc-sample/output <<'__EOF__'
  879. Output from demo, excluding Char class:
  880.  
  881. Include the Char class in the demo? (y/n): n
  882. queue:   5, stack:-5.0
  883. queue: 4.0, stack:  -4
  884. queue:   3, stack:-3.0
  885. queue: 2.0, stack:  -2
  886. queue:   1, stack:-1.0
  887. queue: 0.0, stack:   0
  888. queue:  -1, stack: 1.0
  889. queue:-2.0, stack:   2
  890. queue:  -3, stack: 3.0
  891. queue:-4.0, stack:   4
  892. queue:  -5, stack: 5.0
  893.  
  894. Output from demo, including Char class:
  895.  
  896. Include the Char class in the demo? (y/n): y
  897. queue:   5, stack:   h
  898. queue:   q, stack:-4.0
  899. queue:   3, stack:   j
  900. queue:   o, stack:-2.0
  901. queue:   1, stack:   l
  902. queue:   m, stack: 0.0
  903. queue:  -1, stack:   n
  904. queue:   k, stack: 2.0
  905. queue:  -3, stack:   p
  906. queue:   i, stack: 4.0
  907. queue:  -5, stack:   r
  908. __EOF__
  909. set `wc -lwc <objc-sample/output`
  910. if test $1$2$3 != 29111679
  911. then
  912.     echo ERROR: wc results of objc-sample/output are $* should be 29 111 679
  913. fi
  914.  
  915. chmod 644 objc-sample/output
  916.  
  917. if test -f objc-sample/COPYRIGHT
  918. then
  919.     echo Ok to overwrite existing file objc-sample/COPYRIGHT\?
  920.     read answer
  921.     case "$answer" in
  922.     [yY]*)    echo Proceeding;;
  923.     *)    echo Aborting; exit 1;;
  924.     esac
  925.     rm -f objc-sample/COPYRIGHT
  926.     if test -f objc-sample/COPYRIGHT
  927.     then
  928.         echo Error: could not remove objc-sample/COPYRIGHT, aborting
  929.         exit 1
  930.     fi
  931. fi
  932. echo x - objc-sample/COPYRIGHT
  933. cat >objc-sample/COPYRIGHT <<'__EOF__'
  934. This copyright notice applies to all source files distributed in the
  935. comp.lang.objective-c FAQ: `A Simple Sample Objective-C program'.
  936.  
  937. Copyright (C) 1993 Paul J. Sanchez and Bill Shirley
  938. Copyright (C) 1994, 1996 Pieter J. Schoenmakers
  939.  
  940. The `simple sample Objective-C program' is free software; you can
  941. redistribute it and/or modify it under the terms of the GNU General Public
  942. License as published by the Free Software Foundation; either version 2, or
  943. (at your option) any later version.
  944.  
  945. The `simple sample Objective-C program' is distributed in the hope that it
  946. will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  947. of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
  948. Public License for more details.
  949.  
  950. You should have received a copy of the GNU General Public License along
  951. with GNU Emacs; see the file COPYING.  If not, write to the Free Software
  952. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  953. __EOF__
  954. set `wc -lwc <objc-sample/COPYRIGHT`
  955. if test $1$2$3 != 19155973
  956. then
  957.     echo ERROR: wc results of objc-sample/COPYRIGHT are $* should be 19 155 973
  958. fi
  959.  
  960. chmod 644 objc-sample/COPYRIGHT
  961.  
  962. chmod 755 objc-sample
  963.  
  964. exit 0
  965.